﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace nhCore.Modbus
{
    public class ConfigAnalyzer : Analyzer
    {
        /// <summary>
        /// 解析采集仪配置
        /// </summary>
        public ConfigAnalyzer()
        {
            Name = "解析采集仪配置";
        }

        /// <summary>
        /// 解析读配置返回帧
        /// </summary>
        /// <param name="byts">返回帧</param>
        /// <returns>配置字典</returns>
        public override object Analysis(object o)
        {
            byte[] byts = o as byte[];
            FrameValid mb = new FrameValid(byts, true);
            return BytesToDbConfig(mb.Data, mb.Address);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <param name="address"></param>
        /// <returns></returns>
        public static Dictionary<byte, List<DbConfig>> BytesToDbConfig(byte[] data, byte address = 8)
        {
            char[] charJJJJ = { 'J', 'J', 'J', 'J' };
            char[] charXXXXXX = { 'X', 'X', 'X', 'X', 'X', 'X' };

            string[] process = { //12H量处理对应的统计方式
                "AVG", //0: 瞬时值  AVG
                "SUM", //1: 累加值  SUM
                "SUM", //2: 负差值 初值-当前 SUM
                "SUM", //3: 正差值 当前-初值 SUM
                "NOT", //4: 风向瞬时值 NOT
                "AVG", //5: 平均值(分) AVG
                "NOT", //6: 未定义 NOT
                "SUM"  //7: 时间积分 + 0.5为四舍五入 SUM
            };

            Tuple<string, string, string>[] typeStatistics =
            {
                new Tuple<string, string, string>("风向", "FengXiang", "NOT"),
                new Tuple<string, string, string>("风速", "FengSu", "AVG"),
                new Tuple<string, string, string>("降雨", "JiangYu", "SUM"),
                new Tuple<string, string, string>("蒸发", "ZhengFa", "SUM")
            };

            Dictionary<byte, List<DbConfig>> ls = new Dictionary<byte, List<DbConfig>>
            {
                { address, new List<DbConfig>() }
            };
            DbConfig cfg = new DbConfig();//记录仪中读出的配置文件要素
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);//对引用的编码进行注册
            string strTmp = Encoding.GetEncoding("gb2312").GetString(data, 0, 16).Trim();
            int index = strTmp.LastIndexOf('0');
            if (index >= 0)//字符中有0才做处理
            {
                int len = 0;
                while (strTmp[index] == '0' || strTmp[index] == '.')
                {   //index跳过数字
                    len += 1;
                    index -= 1;
                }

                cfg.Display = strTmp.Substring(0, index + 1).Trim();//要素标题 index+1是长度

                cfg.Unit = strTmp.Substring(index + 1 + len).Trim()//index是最后一个非0位置
                    .TrimEnd(charJJJJ).TrimEnd(charXXXXXX);//要素单位
                string strD = strTmp.Substring(index + 1, len).Trim();
                index = strD.IndexOf('.');
                if (index == -1)
                {
                    cfg.Digits = 0;
                }
                else
                {
                    cfg.Digits = strD.Length - index - 1;
                }

                cfg.Address = address;
                cfg.Index = data[16];//对应10H寄存器地址

                if (strTmp.Contains("XXXXXX"))//风向
                {
                    cfg.Type = "FengXiang";
                    cfg.Statistics = "NOT";
                }
                else
                {
                    cfg.Statistics = process[data[18]]; //对应12H量处理

                    foreach (var dt in typeStatistics) //根据要素名确定类型及统计方式
                    {
                        if (cfg.Display.ToLower().Contains(dt.Item1.ToLower()))//是否包含对应字符串
                        {
                            cfg.Type = dt.Item2;
                            break;
                        }
                    }
                }

                if (data[19] == 7)//对应13H特别处理
                {   //7为485重复
                    DbConfig t;
                    string strName = cfg.Display.Substring(0, cfg.Display.Length - 2);
                    for (byte i = 1; i <= data[24]; i++)//对应18H 485重复要素数 
                    {   
                        t = new DbConfig()//加重复要素
                        {
                            Display = strName + i.ToString().PadLeft(2, '0'),
                            Address = cfg.Address,
                            Index = (byte)(cfg.Index + i - 1),
                            Digits = cfg.Digits,
                            Unit = cfg.Unit,
                            Type = cfg.Type,
                            Statistics = cfg.Statistics,
                        };
                        ls[address].Add(t);
                    }
                }
                else
                {
                    ls[address].Add(cfg);
                }
            }
            return ls;

        }
    }
    //写00 10 10 00 00 10 20 C6 F8 CE C2 20 20 20 20 20 30 30 2E 30 20 A1 E6 03 00 00 00 00 00 00 00 00 00 07 D0 07 D0 B6 C0 57 45
    //读00 11 10 00 00 10 F9 14 
    //回09 11 20 B7 E7 CB D9 20 30 30 2E 30 6D 2F 73 4A 4A 4A 4A 06 00 00 00 00 00 00 C8 00 00 06 40 02 58 DC 4C FC 25
}
